//备注：拷贝代码请加上作者信息
//作者：王海涛
//邮箱：1126471088@qq.com
//版本：V0.1.0
#include "Ring_Queue.h"
#include <string.h>

/*环形队列结构体*/
typedef struct
{
    volatile short Write_Mutex;//写锁
    volatile short Read_Mutex; //读锁
    unsigned char* Buffer;      //FIFO缓存
    unsigned short Buffer_Size; //FIFO缓存大小
    unsigned short Data_Size;   //有效数据个数
    unsigned short Write_Index; //写索引
    unsigned short Read_Index;  //读索引

    unsigned short Queue_Max_Count;  //队列最大个数
    unsigned short Queue_Write_Index;//队列写索引
    unsigned short Queue_Read_Index; //队列读索引
    unsigned short Queue[1];         //每个队列里的长度
}WHT_Handle_t;

#define WHT_Ring_Queue_Hadnle    ((WHT_Handle_t*)handle)

/*初始化环形队列*/
static void WHT_Init(WHT_Ring_Queue_Handle_t* handle, unsigned char* buffer, unsigned short buffer_size, unsigned short queue_count)
{
    *handle = buffer_size < (sizeof(WHT_Handle_t) + sizeof(unsigned short) * queue_count) ? (WHT_Ring_Queue_Handle_t)0 : (WHT_Ring_Queue_Handle_t)buffer;
    if (*handle == (WHT_Ring_Queue_Handle_t)0)
        return;
    else
    {
        WHT_Handle_t* WHT_Handle = (WHT_Handle_t*)buffer;

        WHT_Handle->Write_Mutex = 0;
        WHT_Handle->Read_Mutex = 0;
        WHT_Handle->Buffer = buffer + sizeof(WHT_Handle_t) + sizeof(unsigned short) * queue_count;
        WHT_Handle->Buffer_Size = buffer_size - sizeof(WHT_Handle_t) - sizeof(unsigned short) * queue_count;
        WHT_Handle->Data_Size = 0;
        WHT_Handle->Write_Index = 0;
        WHT_Handle->Read_Index = 0;
        WHT_Handle->Queue_Max_Count = queue_count;
        WHT_Handle->Queue_Write_Index = 0;
        WHT_Handle->Queue_Read_Index = 0;
        memset(WHT_Handle->Queue, 0, queue_count);
    }
}
/*获取环形队列是否为空*/
static unsigned short WHT_Ring_Queue_Get_Empty_State(const WHT_Ring_Queue_Handle_t handle)
{
    return WHT_Ring_Queue_Hadnle->Queue[WHT_Ring_Queue_Hadnle->Queue_Read_Index] == 0 ? 0 : 1;
}
/*获取环形队列空闲大小*/
static unsigned short WHT_Ring_Queue_Get_Idle_Size(const WHT_Ring_Queue_Handle_t handle)
{
    return (WHT_Ring_Queue_Hadnle->Buffer_Size - WHT_Ring_Queue_Hadnle->Data_Size);
}
/*FIFO写环形队列,返回写入的个数*/
static unsigned short WHT_Ring_Queue_Write(const WHT_Ring_Queue_Handle_t handle, const unsigned char* input_buffer, unsigned short length)
{
    unsigned short memcpy_count;

    if (WHT_Ring_Queue_Get_Idle_Size(handle) < length)//空间不足无法写入队列
        return 0;
    if (WHT_Ring_Queue_Hadnle->Queue[WHT_Ring_Queue_Hadnle->Queue_Write_Index] != 0)//最早队列未读取
        return 0;
    if (WHT_Ring_Queue_Hadnle->Write_Mutex != 0)//写锁打开则不写入
        return 0;
    else
        WHT_Ring_Queue_Hadnle->Write_Mutex = 1;
    
    memcpy_count = WHT_Ring_Queue_Hadnle->Buffer_Size - WHT_Ring_Queue_Hadnle->Write_Index;
    memcpy_count = memcpy_count > length ? length : memcpy_count;
    if (memcpy_count)
    {
        memcpy(&WHT_Ring_Queue_Hadnle->Buffer[WHT_Ring_Queue_Hadnle->Write_Index], input_buffer, memcpy_count);
        WHT_Ring_Queue_Hadnle->Write_Index = (WHT_Ring_Queue_Hadnle->Write_Index + memcpy_count) % WHT_Ring_Queue_Hadnle->Buffer_Size;
        input_buffer += memcpy_count;
    }
    memcpy_count = length - memcpy_count;
    if (memcpy_count)
    {
        memcpy(&WHT_Ring_Queue_Hadnle->Buffer[WHT_Ring_Queue_Hadnle->Write_Index], input_buffer, memcpy_count);
        WHT_Ring_Queue_Hadnle->Write_Index = (WHT_Ring_Queue_Hadnle->Write_Index + memcpy_count) % WHT_Ring_Queue_Hadnle->Buffer_Size;
    }
    WHT_Ring_Queue_Hadnle->Data_Size += length;
    WHT_Ring_Queue_Hadnle->Queue[WHT_Ring_Queue_Hadnle->Queue_Write_Index] = length;
    WHT_Ring_Queue_Hadnle->Queue_Write_Index = (WHT_Ring_Queue_Hadnle->Queue_Write_Index + 1) % WHT_Ring_Queue_Hadnle->Queue_Max_Count;
    WHT_Ring_Queue_Hadnle->Write_Mutex = 0;
    return length;
}
/*FIFO读环形队列,返回读取的个数*/
static unsigned short WHT_Ring_Queue_Read(const WHT_Ring_Queue_Handle_t handle, unsigned char* ontput_buffer, unsigned short expected_length)
{
    unsigned short Message_Count;
    unsigned short Read_Count;

    if (WHT_Ring_Queue_Hadnle->Read_Mutex != 0)
        return 0;
    else
        WHT_Ring_Queue_Hadnle->Read_Mutex = 1;

    Message_Count = WHT_Ring_Queue_Hadnle->Queue[WHT_Ring_Queue_Hadnle->Queue_Read_Index];//原始包大小
    Read_Count = Message_Count > expected_length ? expected_length : Message_Count;
    for (unsigned short i = 0; i < Read_Count; i++)
    {
        ontput_buffer[i] = WHT_Ring_Queue_Hadnle->Buffer[WHT_Ring_Queue_Hadnle->Read_Index];
        WHT_Ring_Queue_Hadnle->Read_Index = (WHT_Ring_Queue_Hadnle->Read_Index + 1) % WHT_Ring_Queue_Hadnle->Buffer_Size;
    }
    WHT_Ring_Queue_Hadnle->Data_Size -= Message_Count;
    WHT_Ring_Queue_Hadnle->Read_Index = (WHT_Ring_Queue_Hadnle->Read_Index + Message_Count - Read_Count) % WHT_Ring_Queue_Hadnle->Buffer_Size;//偏移到下一包;
    WHT_Ring_Queue_Hadnle->Queue[WHT_Ring_Queue_Hadnle->Queue_Read_Index] = 0;//清零
    WHT_Ring_Queue_Hadnle->Queue_Read_Index = (WHT_Ring_Queue_Hadnle->Queue_Read_Index + 1) % WHT_Ring_Queue_Hadnle->Queue_Max_Count;
    WHT_Ring_Queue_Hadnle->Read_Mutex = 0;
    return Read_Count;
}

/*全局常量*/
const WHT_Ring_Queue_t WHT_Ring_Queue = 
{
    .WHT_Register        = WHT_Init,
    .WHT_Get_Empty_State = WHT_Ring_Queue_Get_Empty_State,
    .WHT_Get_Idle_Size   = WHT_Ring_Queue_Get_Idle_Size,
    .WHT_Write           = WHT_Ring_Queue_Write,
    .WHT_Read            = WHT_Ring_Queue_Read,
};
